package com.zcoj.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcoj.core.model.PageData;
import com.zcoj.core.model.PageWrap;
import com.zcoj.mapper.ContestProblemMapper;
import com.zcoj.mapper.ContestRecordMapper;
import com.zcoj.pojo.Dto.ContestProblem;
import com.zcoj.pojo.Dto.ContestRecord;
import com.zcoj.pojo.Dto.User;
import com.zcoj.pojo.Vo.ContestRankSingleProblemInfoVO;
import com.zcoj.pojo.Vo.ContestRankVO;
import com.zcoj.service.ContestProblemService;
import com.zcoj.service.ContestRecordService;
import com.zcoj.service.UserService;
import com.zcoj.util.WrapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * Service实现
 * @author 剩xia的盛夏
 * @date 2023/02/24 16:16
 */
@Service
public class ContestRecordServiceImpl implements ContestRecordService {

    @Autowired
    private ContestRecordMapper contestRecordMapper;

    @Autowired
    private ContestProblemService contestProblemService;

    @Autowired
    private ContestProblemMapper contestProblemMapper;

    @Autowired
    private UserService userService;

    @Override
    public Integer create(ContestRecord contestRecord) {
        contestRecordMapper.insert(contestRecord);
        return contestRecord.getId();
    }

    @Override
    public void deleteById(Integer id) {
        contestRecordMapper.deleteById(id);
    }

    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) return;
        contestRecordMapper.deleteBatchIds(ids);
    }

    @Override
    public void updateById(ContestRecord contestRecord) {
        contestRecordMapper.updateById(contestRecord);
    }

    @Override
    public void updateByIdInBatch(List<ContestRecord> contestRecords) {
        if (CollectionUtils.isEmpty(contestRecords)) return;
        for (ContestRecord contestRecord: contestRecords) {
            this.updateById(contestRecord);
        }
    }

    @Override
    public ContestRecord findById(Integer id) {
        return contestRecordMapper.selectById(id);
    }

    @Override
    public ContestRecord findOne(ContestRecord contestRecord) {
        Wrapper<ContestRecord> wrapper = new QueryWrapper<>(contestRecord);
        return contestRecordMapper.selectOne(wrapper);
    }

    @Override
    public List<ContestRecord> findList(ContestRecord contestRecord) {
        Wrapper<ContestRecord> wrapper = new QueryWrapper<>(contestRecord);
        return contestRecordMapper.selectList(wrapper);
    }
  
    @Override
    public PageData<ContestRecord> findPage(PageWrap<ContestRecord> pageWrap) {
        IPage<ContestRecord> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<ContestRecord> queryWrapper = new QueryWrapper<>(WrapperUtil.blankToNull(pageWrap.getModel()));
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        return PageData.from(contestRecordMapper.selectPage(page, queryWrapper));
    }

    @Override
    public List<ContestRankVO> contestIORank(Integer cid) {
        List<ContestRankVO> contestRankVOList=new ArrayList<>();
        ContestProblem contestProblem = new ContestProblem();
        contestProblem.setCid(cid);
        List<ContestProblem> contestProblemServiceList = contestProblemService.findList(contestProblem);
        //List<ContestRankSingleProblemInfoVO> contestRankSingleProblemInfoVOS=new ArrayList<>();
        QueryWrapper<ContestRecord> contestRecordQueryWrapper=new QueryWrapper<>();
        contestRecordQueryWrapper.eq("cid",cid).select("uid");
        List<ContestRecord> contestRecordList = contestRecordMapper.selectList(contestRecordQueryWrapper);

        Set<Integer> userHashSet=new HashSet<>();
        for (ContestRecord contestRecord : contestRecordList) {
            userHashSet.add(contestRecord.getUid());
        }

        for (Integer uid : userHashSet) {
            ContestRankVO contestRankVO = new ContestRankVO();
            User userById = userService.findById(uid);
            contestRankVO.setUid(uid);
            contestRankVO.setUsername(userById.getUsername());
            contestRankVO.setRealname(userById.getRealname());
            List<ContestRankSingleProblemInfoVO> contestRankSingleProblemInfoVOS=new ArrayList<>();
            for (ContestProblem cp : contestProblemServiceList) {
                ContestRankSingleProblemInfoVO contestRankSingleProblemInfoVO = new ContestRankSingleProblemInfoVO();
                contestRankSingleProblemInfoVO.setPid(cp.getPid());
                contestRankSingleProblemInfoVO.setIsFirstSubmit(false);

                QueryWrapper<ContestRecord> queryWrapperCR=new QueryWrapper<>();
                //判断使用是否提交
                queryWrapperCR.eq("uid",uid).eq("cid",cid).eq("pid",cp.getPid());
                Integer selectCount = contestRecordMapper.selectCount(queryWrapperCR);
                if(selectCount!=0) {//不等于0说明有提交记录
                    //在查是否AC
                    queryWrapperCR.clear();
                    queryWrapperCR.eq("uid",uid).eq("cid",cid).eq("pid",cp.getPid()).eq("status",1);
                    Integer selectCountByAc = contestRecordMapper.selectCount(queryWrapperCR);
                    if(selectCountByAc!=0){//ac
                        contestRankSingleProblemInfoVO.setColor("0,255,0");//设置绿色
                        queryWrapperCR.clear();
                        queryWrapperCR.eq("uid",uid).eq("cid",cid).eq("pid",cp.getPid()).eq("checked",0);
                        Integer selectCount1 = contestRecordMapper.selectCount(queryWrapperCR);
                        contestRankSingleProblemInfoVO.setSubmitNumber(selectCount1);
                        queryWrapperCR.eq("status",1);
                        ContestRecord contestRecord1 = contestRecordMapper.selectOne(queryWrapperCR);
                        contestRankSingleProblemInfoVO.setConsumeTime(contestRecord1.getTime());
                        contestRankSingleProblemInfoVO.setScore(contestRecord1.getScore());
                        if(contestRecord1.getFirstBlood()){
                            contestRankSingleProblemInfoVO.setIsFirstSubmit(contestRecord1.getFirstBlood());
                        }
                    }else {//没有通过的
                        contestRankSingleProblemInfoVO.setColor("255,0,0");//设置红色
                        queryWrapperCR.clear();
                        queryWrapperCR.eq("uid",uid).eq("cid",cid).eq("pid",cp.getPid());
                        List<ContestRecord> contestRecords = contestRecordMapper.selectList(queryWrapperCR);
                        int maxScore=0;//会有部分通过
                        for (ContestRecord contestRecord : contestRecords) {
                            if(contestRecord.getScore()>maxScore){
                                contestRankSingleProblemInfoVO.setConsumeTime(contestRecord.getTime());
                                maxScore=contestRecord.getScore();
                            }
                        }
                        contestRankSingleProblemInfoVO.setScore(maxScore);
                        contestRankSingleProblemInfoVO.setSubmitNumber(contestRecords.size());
                    }
                }else {
                    contestRankSingleProblemInfoVO.setScore(0);
                    contestRankSingleProblemInfoVO.setConsumeTime(0L);
                    contestRankSingleProblemInfoVO.setSubmitNumber(0);
                    contestRankSingleProblemInfoVO.setColor("0,0,0");
                }
                contestRankSingleProblemInfoVOS.add(contestRankSingleProblemInfoVO);
            }

            contestRankVO.setContestRankSingleProblemInfos(contestRankSingleProblemInfoVOS);
            contestRankVOList.add(contestRankVO);
        }

        //排序
        contestRankVOList.sort(new Comparator<ContestRankVO>() {
            @Override
            public int compare(ContestRankVO o1, ContestRankVO o2) {
                // 按sumScore从大到小排序
                int scoreCompare = o2.getSumScore().compareTo(o1.getSumScore());
                if (scoreCompare != 0) {
                    return scoreCompare;
                }
                // 如果sumScore相等，在按sumTime从小到大排序
                return o1.getSumTime().compareTo(o2.getSumTime());
            }
        });
        return contestRankVOList;
    }

    @Override
    public List<Integer> getContestProblemID(Integer cid) {
        QueryWrapper<ContestProblem> contestProblemQueryWrapper=new QueryWrapper<>();
        contestProblemQueryWrapper.eq("cid",cid).select("pid");
        List<ContestProblem> contestProblems = contestProblemMapper.selectList(contestProblemQueryWrapper);
        List<Integer> list=new ArrayList<>();
        for (ContestProblem contestProblem : contestProblems) {
            list.add(contestProblem.getPid());
        }
        return list;
    }

    @Override
    public long count(ContestRecord contestRecord) {
        Wrapper<ContestRecord> wrapper = new QueryWrapper<>(contestRecord);
        return contestRecordMapper.selectCount(wrapper);
    }
}
